home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- #
- # Apple Developer Technical Support
- #
- # SmallDaemon
- # A small faceless background-only application
- #
- # main.c - C Source
- #
- # Copyright © 1991 Apple Computer, Inc.
- # All rights reserved.
- #
- # Versions:
- # 1.0 09/91 C.K. Haun <TR>
- #
- # Components:
- # main.c
- # AppleEvents.c
- #
- # This is a _very_ simple sample showing a do-nothing
- # System 7.0 faceless background application.
- #
- # The main things to note are....
- # 1) Look at the SIZE resource for the flag settings you'll
- # need to let the Finder™ know that you only want to work
- # in the background.
- # 2) Notice that you really do have your own heap and your own
- # event loop. You can do anything a foreground application
- # can do, send AppleEvents, PPC stuff, anything else you'd
- # like EXCEPT a graphic interface.
- # 3) NOTE that no managers are started up. You cannot start up
- # Window, Menu, Dialogs, or anything else that
- # deals with the graphic front end. Just leave them out.
- # You _can_ start up QuickDraw, if you want to use some QuickDraw
- # functions (like offscreen ports), but you CANNOT actually
- # do any screen drawing.
- #
- # Of course, a backgrounder can be launched from the Finder™
- # with a double-click. However, if you'd like the backgrounder
- # to perform some useful service for your main application, driver,
- # DA, or whatever, you will want it running all the time.
- # The BEST way to insure this is to install the backgrounder in the
- # StartUp Items folder in the system folder. This will insure that
- # it is always launched, and it will also reduce memory fragmentation
- # since it will be installed at startup time. You can search for it
- # when you need it with IPCListPorts (see the PPC toolbox documentation).
- # Optionally, you can use the LaunchApplication trap to launch it
- # when you need it, and kill it when you're done. But this could
- # cause some multiFinder heap fragmentation.
- #
- # And remember, it's a backgrounder, you can't see it. To kill it
- # use TaskIt or ProcDoggie.
- #
- # ---------------------------------------------------------------
- # Use this sample as a starting point, and adapt its' routines to
- # meet the specific needs of your project.
- #
- ------------------------------------------------------------------------------*/
-
- /* This doesn't do much but wait for a quit event. But, you can expand it */
- /* to suit whatever your needs are for a backgrounder. */
- /* Be sure to look at the SIZE resource for this app to see how the */
- /* flags should be set for a background-only task */
- #include <memory.h>
- #include <appleevents.h>
- #include <events.h>
- #include <types.h>
- #include <gestaltequ.h>
- #include <SegLoad.h>
- #include "pb.h"
-
- /* variables */
- Boolean gQuit = false;
- EventRecord gERecord;
- Boolean gHasAppleEvents;
- unsigned long gMySleep = 120; /* long time, long time. Change this if */
- /* you'd like to do null processing. Just keep in mind that the */
- /* user does NOT know that you exist, and if you are eating */
- /* up a bunch of time the user will not know why his or her */
- /* machine is slowing down. */
-
- /* structs */
- /* a little struct to install handlers from. Makes it easier to plug in */
- /* new handlers */
- struct AEinstalls {
- AEEventClass theClass;
- AEEventID theEvent;
- EventHandlerProcPtr theProc;
- };
- typedef struct AEinstalls AEinstalls;
-
- /* prototypes for this file */
- pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
- void DoHighLevel(EventRecord *AERecord);
- void InitAEStuff(void);
-
- main()
- {
- /* We are NOT initializing any managers. We're in the background, with no */
- /* face, we can't use windows or dialogs or menus. If you need to talk to the */
- /* user you can post a notification, or launch an application to communicate */
- /* Passing an AppleEvent in the launchapplication trap could do the */
- /* communication for you. */
- #ifdef MPW
- extern void _DataInit();
-
- UnloadSeg((Ptr)_DataInit);
- #endif
- InitGraf((Ptr) &qd.thePort);
- /* Routine to install Apple event handlers */
- InitAEStuff();
-
- InitPrefs(); // opens the prefs resource file, reads in the user's times
-
- InitPortableStuff();
-
- /* no nothing but high level events */
- while (gQuit == false) {
- WaitNextEvent(highLevelEventMask, &gERecord, gMySleep, 0);
- CheckForMains();
- switch (gERecord.what) {
- case kHighLevelEvent:
- DoHighLevel(&gERecord);
- break;
- }
- }
- }
-
- /* Here are the AppleEvent handlers for this background-only task. */
- /* Since this is a real live application, it can accept and send any */
- /* Apple Events you want to send or receive. */
- /* In this case, the only ones that make any sense in this app are */
- /* 'oapp' and 'quit' */
-
-
- /* InitAEStuff checks for the availability of the AppleEvent Manager and */
- /* installs our event handlers. */
- /* if the AEM isn't around, we bail. */
- void InitAEStuff(void)
- {
- static AEinstalls HandlersToInstall[] = {
- {
- kCoreEventClass, kAEOpenApplication, AEOpenHandler
- }, {
- kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
- }, {
- kCoreEventClass, kAEQuitApplication, AEQuitHandler
- }, {
- kCoreEventClass, kAEPrintDocuments, AEPrintHandler
- },
- /* The above are the four required AppleEvents. */
- };
-
- OSErr aevtErr = noErr;
- long aLong = 0;
- Boolean gHasAppleEvents = false;
- /* Check this machine for AppleEvents. If they are not here (ie not 7.0)
- * then we exit */
- gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
- /* The following series of calls installs all our AppleEvent Handlers.
- * These handlers are added to the application event handler list that
- * the AppleEvent manager maintains. So, whenever an AppleEvent happens
- * and we call AEProcessEvent, the AppleEvent manager will check our
- * list of handlers and dispatch to it if there is one.
- */
- if (gHasAppleEvents) {
- register qq;
- for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
- aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
- HandlersToInstall[qq].theProc, 0, false);
- if (aevtErr) {
- /* Of course, you can't tell the user why you died directly, since you have no face. */
- /* But, you can post a notification from here to let them know. */
- ExitToShell(); /* just fail, baby */
- }
- }
- } else {
- ExitToShell();
- }
- }
-
- /* end InitAEStuff */
-
- void DoHighLevel(EventRecord *AERecord)
- {
- /* I'm not doing any error handling here because there's not a lot */
- /* I can do, just pass the errors back. */
- AEProcessAppleEvent(AERecord);
-
- }
-
- /* end DoHighLevel */
-
-
- /* This is the standard Open Application event. */
- pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (messagein,reply,refIn)
- /* we of course don't do anything here, since we're background only */
- /* But this was a normal launch, so return noErr */
- return(noErr);
- }
-
- /* end AEOpenHandler */
-
- /* Open Doc, opens our documents. */
- /* In this case, of course, you are in the background so you should return an error */
- /* here since you're not opening a document. */
- /* Of course, you _might_ want to open a doc, but you will probably */
- /* confuse the user if you do, since they will see no action as the */
- /* result of their clicking on a document icon. */
- pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (reply, refIn,messagein)
- /* we of course don't do anything here, so tell the sender that we */
- /* didn't handle the event */
- return(errAEEventNotHandled);
- }
-
- /* same logic for printing */
- pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (reply,refIn,messagein)
- /* we of course don't do anything here */
- return(errAEEventNotHandled);
- }
-
- /* Standard Quit event handler, to handle a Quit event from the Finder, for example. */
- /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life. */
- pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
- {
- #pragma unused (messagein,refIn,reply)
- extern Boolean Quit;
- /* This does _NOT_ quit, you */
- /* should NEVER quit from an AppleEvent handler. Calling */
- /* ExitToShell here would blow up the Finder™ */
- SetRest();
- SetSysSleep(gSysSleep);
- SetHDSleep(gHDSleep);
- gQuit = true;
- return(noErr);
- }
-